/**
* Utility functions for looping over 
* particular sets of verticies.
*/

#ifndef SELECT_UTIL_H
#define SELECT_UTIL_H

#include <OGF/cells/common/common.h>
#include <OGF/cells/map/map.h>
#include <OGF/cells/map/map_attributes.h>

#include <OGF/surface/grob/surface.h>

#include <vector>
#include <iostream>

namespace OGF {

/**
* Do a for loop over all the vertices sharing an edge with 'vert'.
* Map::Vertex *v must be defined before calling this.
*/
#define FOR_EACH_ADJACENT_VERTEX(vert, v)									\
for(																		\
	Map::Halfedge *edge_MACRO = vert->halfedge(), *first_MACRO = nil;		\
	(v = edge_MACRO->opposite()->vertex()) && (edge_MACRO != first_MACRO);	\
	edge_MACRO = edge_MACRO->next_around_vertex(),							\
	first_MACRO = vert->halfedge()											\
)

/**
* Do a for loop over all the outward edges from 'vert'.
* Map::Halfedge *he must be defined before calling this.
*/
#define FOR_EACH_ADJACENT_OUTEDGE(vert, he)									\
for(																		\
	Map::Halfedge *edge_MACRO = vert->halfedge(), *first_MACRO = nil;		\
	(he = edge_MACRO->opposite()) && (edge_MACRO != first_MACRO);	\
	edge_MACRO = edge_MACRO->next_around_vertex(),							\
	first_MACRO = vert->halfedge()											\
)


/**
* Do a for loop over all the faces attached to 'vert'.
* Map::Facet *f must be defined before calling this.
*/
#define FOR_EACH_ADJACENT_FACE(vert, f)										\
for(																		\
	Map::Halfedge *edge_MACRO = vert->halfedge(), *first_MACRO = nil;		\
	(f = edge_MACRO->facet()) && (edge_MACRO != first_MACRO);				\
	edge_MACRO = edge_MACRO->next_around_vertex(),							\
	first_MACRO = vert->halfedge()											\
)


/**
* Do a for loop over all the vertices in the face.
* Map::Vertex *v must be defined before calling this.
*/
#define FOR_EACH_VERTEX_IN_FACE(face, v)									\
for(																		\
	Map::Halfedge *edge_MACRO = face->halfedge(), *first_MACRO = nil;		\
	(v = edge_MACRO->vertex()) && (edge_MACRO != first_MACRO);				\
	edge_MACRO = edge_MACRO->next(),										\
	first_MACRO = face->halfedge()											\
)


class Select
{
public:
	/**
	* Get a list of all the verticies adjacent to the argument.
	*/
	static std::vector<Map::Vertex*> adjacent_verts(Map::Vertex *vert)
	{
		Map::Vertex *v;
		std::vector<Map::Vertex*> list;
		FOR_EACH_ADJACENT_VERTEX(vert, v);
		{
			list.push_back(v);
		}

		return list;
	}
	/**
	* Get a list of all the verticies in this face
	*/
	static std::vector<Map::Vertex*> verts_in_face(Map::Facet *face)
	{
		Map::Vertex *v;
		std::vector<Map::Vertex*> list;

		FOR_EACH_VERTEX_IN_FACE(face, v);
		{
			list.push_back(v);
		}

		return list;
	}



};

} //namespace


#endif
